package com.imut.lagain.service.impl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imut.lagain.entity.User;
import com.imut.lagain.repository.UserRepository;
import com.imut.lagain.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户服务实现类
 */
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserRepository, User> implements IUserService {
    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    /**
     * 根据openid查询用户
     * @param openid 微信openid
     * @return 用户信息
     */
    @Override
    public User getUserByOpenid(String openid) {
        if (!StringUtils.hasText(openid)) {
            return null;
        }
        return baseMapper.findByOpenid(openid);
    }
    
    /**
     * 根据unionid查询用户
     * @param unionid 微信unionid
     * @return 用户信息
     */
    public User getUserByUnionid(String unionid) {
        if (!StringUtils.hasText(unionid)) {
            return null;
        }
        return baseMapper.findByUnionid(unionid);
    }
    
    /**
     * 根据手机号查询用户
     * @param phone 手机号
     * @return 用户信息
     */
    @Override
    public User getUserByPhone(String phone) {
        log.info("根据手机号查找用户: phone={}", phone);
        try {
            if (!StringUtils.hasText(phone)) {
                log.warn("手机号为空");
                return null;
            }
            
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("phone", phone);
            queryWrapper.eq("is_deleted", false);
            
            User user = this.getOne(queryWrapper);
            log.info("根据手机号查找用户结果: user={}", user != null ? "找到用户" : "未找到用户");
            
            if (user != null) {
                log.debug("用户详细信息: id={}, openid={}, nickname={}, phone={}", 
                    user.getId(), user.getOpenid(), user.getNickname(), user.getPhone());
            }
            
            return user;
        } catch (Exception e) {
            log.error("根据手机号查找用户异常: phone={}, error={}", phone, e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 根据用户名查询用户（实际使用nickname字段）
     * @param username 用户名（实际为nickname）
     * @return 用户信息
     */
    @Override
    public User findByUsername(String username) {
        if (!StringUtils.hasText(username)) {
            return null;
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("nickname", username);
        queryWrapper.eq("is_deleted", false);
        return this.getOne(queryWrapper);
    }
    
    /**
     * 创建新用户
     * @param openid 微信openid
     * @param unionid 微信unionid
     * @param nickname 昵称
     * @param avatarUrl 头像URL
     * @param phone 手机号
     * @return 创建的用户
     */
    public User createUser(String openid, String unionid, String nickname, String avatarUrl, String phone) {
        User user = new User();
        user.setOpenid(openid);
        user.setUnionid(unionid);
        user.setNickname(StringUtils.hasText(nickname) ? nickname : "用户" + System.currentTimeMillis());
        user.setAvatarUrl(avatarUrl);
        user.setPhone(phone);
        user.setIsActive(true);
        user.setIsDeleted(false);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        
        boolean saved = this.save(user);
        if (saved) {
            return user;
        } else {
            log.error("Failed to create user with openid: {}, unionid: {}", openid, unionid);
            return null;
        }
    }
    
    /**
     * 创建新用户（简单版本）
     * @param user 用户对象
     * @return 创建的用户
     */
    @Override
    public User createUser(User user) {
        if (user == null) {
            return null;
        }
        
        // 设置默认值
        if (user.getCreateTime() == null) {
            user.setCreateTime(LocalDateTime.now());
        }
        if (user.getUpdateTime() == null) {
            user.setUpdateTime(LocalDateTime.now());
        }
        if (user.getIsActive() == null) {
            user.setIsActive(true);
        }
        if (user.getIsDeleted() == null) {
            user.setIsDeleted(false);
        }
        
        boolean saved = this.save(user);
        if (saved) {
            log.info("Created user successfully: id={}, nickname={}", user.getId(), user.getNickname());
            return user;
        } else {
            log.error("Failed to create user: nickname={}", user.getNickname());
            return null;
        }
    }
    
    /**
     * 更新用户信息
     * @param user 用户信息
     * @return 是否更新成功
     */
    public boolean updateUser(User user) {
        if (user == null || user.getId() == null) {
            return false;
        }
        user.setUpdateTime(LocalDateTime.now());
        return this.updateById(user);
    }
    
    /**
     * 更新用户信息
     * @param userId 用户ID
     * @param nickname 昵称
     * @param avatarUrl 头像URL
     * @param phone 手机号
     * @return 更新后的用户信息
     */
    public User updateUser(Long userId, String nickname, String avatarUrl, String phone) {
        log.info("开始更新用户信息: userId={}, nickname={}, avatarUrl={}, phone={}", userId, nickname, avatarUrl, phone);
        
        if (userId == null) {
            log.warn("用户ID为空，无法更新用户信息");
            return null;
        }
        
        User user = this.getById(userId);
        if (user == null) {
            log.warn("未找到ID为{}的用户，无法更新用户信息", userId);
            return null;
        }
        
        log.info("找到用户: id={}, nickname={}, avatarUrl={}, phone={}", 
            user.getId(), user.getNickname(), user.getAvatarUrl(), user.getPhone());
        
        boolean needUpdate = false;
        if (StringUtils.hasText(nickname) && !nickname.equals(user.getNickname())) {
            user.setNickname(nickname);
            needUpdate = true;
            log.info("需要更新昵称: {} -> {}", user.getNickname(), nickname);
        }
        if (StringUtils.hasText(avatarUrl) && !avatarUrl.equals(user.getAvatarUrl())) {
            user.setAvatarUrl(avatarUrl);
            needUpdate = true;
            log.info("需要更新头像: {} -> {}", user.getAvatarUrl(), avatarUrl);
        }
        if (StringUtils.hasText(phone) && !phone.equals(user.getPhone())) {
            user.setPhone(phone);
            needUpdate = true;
            log.info("需要更新手机号: {} -> {}", user.getPhone(), phone);
        }
        
        if (needUpdate) {
            user.setUpdateTime(LocalDateTime.now());
            log.info("准备更新用户信息");
            boolean updated = this.updateById(user);
            log.info("更新用户信息结果: updated={}", updated);
            if (updated) {
                log.info("用户信息更新成功");
                return user;
            } else {
                log.error("用户信息更新失败");
                return null;
            }
        } else {
            log.info("用户信息无需更新");
        }
        
        return user;
    }
    
    /**
     * 获取活跃用户列表
     * @param page 分页参数
     * @return 活跃用户分页列表
     */
    @Transactional(readOnly = true)
    public IPage<User> getActiveUsers(Page<User> page) {
        return baseMapper.findActiveUsers(page);
    }
    
    /**
     * 获取活跃用户列表
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 活跃用户分页列表
     */
    @Transactional(readOnly = true)
    public Page<User> getActiveUsers(int pageNum, int pageSize) {
        Page<User> page = new Page<>(pageNum, pageSize);
        return (Page<User>) baseMapper.findActiveUsers(page);
    }
    
    /**
     * 统计用户数量
     * @param isActive 是否活跃（null表示所有用户）
     * @param isDeleted 是否删除（null表示所有用户）
     * @return 用户数量
     */
    @Transactional(readOnly = true)
    public Long countUsers(Boolean isActive, Boolean isDeleted) {
        return baseMapper.countUsers(isActive, isDeleted);
    }
    
    /**
     * 更新用户活跃状态
     * @param userId 用户ID
     * @param isActive 是否活跃
     * @return 是否更新成功
     */
    public boolean updateActiveStatus(Long userId, boolean isActive) {
        if (userId == null) {
            return false;
        }
        int result = baseMapper.updateActiveStatus(userId, isActive);
        if (result > 0) {
            return true;
        }
        return false;
    }
    
    /**
     * 批量更新用户活跃状态
     * @param userIds 用户ID列表
     * @param isActive 是否活跃
     * @return 更新的用户数量
     */
    public int batchUpdateActiveStatus(List<Long> userIds, Boolean isActive) {
        if (userIds == null || userIds.isEmpty()) {
            return 0;
        }
        int result = baseMapper.batchUpdateActiveStatus(userIds, isActive);
        return result;
    }
    
    /**
     * 根据昵称模糊查询用户
     * @param nickname 昵称关键字
     * @param page 分页参数
     * @return 用户分页列表
     */
    @Transactional(readOnly = true)
    public IPage<User> searchUsersByNickname(String nickname, Page<User> page) {
        if (!StringUtils.hasText(nickname)) {
            return new Page<>();
        }
        return baseMapper.findByNicknameLike(nickname, page);
    }
    
    /**
     * 根据昵称模糊查询用户
     * @param nickname 昵称关键字
     * @param pageNum 页码
     * @param pageSize 每页大小
     * @return 用户分页列表
     */
    @Transactional(readOnly = true)
    public Page<User> searchUsersByNickname(String nickname, int pageNum, int pageSize) {
        if (!StringUtils.hasText(nickname)) {
            return new Page<>();
        }
        Page<User> page = new Page<>(pageNum, pageSize);
        return (Page<User>) baseMapper.findByNicknameLike(nickname, page);
    }
    
    /**
     * 软删除用户
     * @param userId 用户ID
     * @return 是否删除成功
     */
    public boolean softDeleteUser(Long userId) {
        if (userId == null) {
            return false;
        }
        User user = this.getById(userId);
        if (user == null) {
            return false;
        }
        user.setIsDeleted(true);
        user.setIsActive(false);
        user.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(user);
        if (result) {
        }
        return result;
    }
    
    /**
     * 恢复已删除的用户
     * @param userId 用户ID
     * @return 是否恢复成功
     */
    public boolean restoreUser(Long userId) {
        if (userId == null) {
            return false;
        }
        User user = this.getById(userId);
        if (user == null) {
            return false;
        }
        user.setIsDeleted(false);
        user.setIsActive(true);
        user.setUpdateTime(LocalDateTime.now());
        boolean result = this.updateById(user);
        if (result) {
        }
        return result;
    }
    
    /**
     * 检查用户是否存在（根据openid或unionid）
     * @param openid 微信openid
     * @param unionid 微信unionid
     * @return 是否存在
     */
    @Transactional(readOnly = true)
    public boolean userExists(String openid, String unionid) {
        if (StringUtils.hasText(openid)) {
            User user = getUserByOpenid(openid);
            if (user != null) {
                return true;
            }
        }
        if (StringUtils.hasText(unionid)) {
            User user = getUserByUnionid(unionid);
            if (user != null) {
                return true;
            }
        }
        return false;
    }
    
    @Override
    public User getOrCreateUser(String openid, String unionid, String nickname, String avatarUrl, String phone) {
        log.info("查找或创建用户: openid={}, unionid={}, nickname={}, phone={}", 
            openid, unionid, nickname, phone);
        
        try {
            // 先根据openid查找用户
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("openid", openid);
            queryWrapper.eq("is_deleted", false);
            
            User user = this.getOne(queryWrapper);
            log.info("根据openid查找用户结果: user={}", user != null ? "找到用户" : "未找到用户");
            
            if (user == null) {
                // 用户不存在，创建新用户
                log.info("用户不存在，创建新用户");
                user = new User();
                user.setOpenid(openid);
                user.setUnionid(unionid);
                user.setNickname(nickname != null ? nickname : "微信用户");
                user.setAvatarUrl(avatarUrl);
                user.setPhone(phone);
                user.setIsActive(true);
                user.setIsDeleted(false);
                user.setCreateTime(LocalDateTime.now());
                user.setUpdateTime(LocalDateTime.now());
                
                boolean saved = this.save(user);
                log.info("创建用户结果: saved={}", saved);
                
                if (saved) {
                    log.info("新用户创建成功: userId={}", user.getId());
                    return user;
                } else {
                    log.error("创建用户失败");
                    return null;
                }
            } else {
                // 用户存在，更新信息
                log.info("用户已存在，更新用户信息");
                boolean needUpdate = false;
                
                if (unionid != null && !unionid.equals(user.getUnionid())) {
                    user.setUnionid(unionid);
                    needUpdate = true;
                    log.info("更新unionid");
                }
                
                if (nickname != null && !nickname.equals(user.getNickname())) {
                    user.setNickname(nickname);
                    needUpdate = true;
                    log.info("更新nickname");
                }
                
                if (avatarUrl != null && !avatarUrl.equals(user.getAvatarUrl())) {
                    user.setAvatarUrl(avatarUrl);
                    needUpdate = true;
                    log.info("更新avatarUrl");
                }
                
                if (phone != null && !phone.equals(user.getPhone())) {
                    user.setPhone(phone);
                    needUpdate = true;
                    log.info("更新phone");
                }
                
                if (needUpdate) {
                    user.setUpdateTime(LocalDateTime.now());
                    boolean updated = this.updateById(user);
                    log.info("更新用户信息结果: updated={}", updated);
                    if (!updated) {
                        log.error("更新用户信息失败");
                    }
                }
                
                log.info("返回现有用户: userId={}", user.getId());
                return user;
            }
        } catch (Exception e) {
            log.error("查找或创建用户异常: openid={}, error={}", openid, e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 查找不活跃用户
     * @param lastActiveTime 最后活跃时间
     * @return 不活跃用户列表
     */
    @Transactional(readOnly = true)
    public List<User> findInactiveUsers(LocalDateTime lastActiveTime) {
        if (lastActiveTime == null) {
            return List.of();
        }
        return baseMapper.findInactiveUsers(lastActiveTime);
    }
    
    /**
     * 查找有openid的活跃用户（用于推送）
     * @return 活跃用户列表
     */
    @Transactional(readOnly = true)
    public List<User> findActiveUsersWithOpenid() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("is_active", true)
                   .eq("is_deleted", false)
                   .isNotNull("openid")
                   .ne("openid", "")
                   .orderByDesc("create_time");
        return this.list(queryWrapper);
    }
    
    /**
     * 统计指定时间范围内的新用户数量
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 新用户数量
     */
    @Transactional(readOnly = true)
    public Long countNewUsers(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime == null || endTime == null) {
            return 0L;
        }
        return baseMapper.countUsersByCreateTime(startTime, endTime);
    }
    
    /**
     * 统计活跃用户数量
     * @return 活跃用户数量
     */
    @Transactional(readOnly = true)
    public Long countActiveUsers() {
        return baseMapper.countUsers(true, false);
    }
    
    /**
     * 统计指定时间范围内的活跃用户数量
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 活跃用户数量
     */
    @Transactional(readOnly = true)
    public Long countActiveUsers(LocalDateTime startTime, LocalDateTime endTime) {
        return baseMapper.countActiveUsersByTimeRange(startTime, endTime);
    }
    
    /**
     * 获取用户统计信息
     * @param userId 用户ID
     * @return 用户统计信息
     */
    @Transactional(readOnly = true)
    public Map<String, Object> getUserStats(Long userId) {
        Map<String, Object> stats = new HashMap<>();
        
        try {
            User user = this.getById(userId);
            if (user == null) {
                stats.put("error", "用户不存在");
                return stats;
            }
            
            stats.put("userId", userId);
            stats.put("nickname", user.getNickname());
            stats.put("createTime", user.getCreateTime());
            stats.put("isActive", user.getIsActive());
            
            // 计算注册天数
            if (user.getCreateTime() != null) {
                long daysSinceRegistration = ChronoUnit.DAYS.between(
                    user.getCreateTime().toLocalDate(), 
                    LocalDate.now()
                );
                stats.put("daysSinceRegistration", daysSinceRegistration);
            }
            
        } catch (Exception e) {
            log.error("获取用户统计信息失败: userId={}", userId, e);
            stats.put("error", e.getMessage());
        }
        
        return stats;
    }
    
    /**
     * 获取伴侣信息
     * @param userId 用户ID
     * @return 伴侣信息
     */
    @Override
    public User getPartnerInfo(Long userId) {
        log.info("开始获取用户伴侣信息: userId={}", userId);
        
        if (userId == null) {
            log.warn("用户ID为空");
            return null;
        }
        
        try {
            // 获取当前用户信息
            User currentUser = baseMapper.findUserById(userId);
            if (currentUser == null) {
                log.warn("当前用户不存在: userId={}", userId);
                return null;
            }
            
            // 检查用户是否绑定了伴侣
            if (currentUser.getPartnerId() == null) {
                log.info("用户未绑定伴侣: userId={}", userId);
                return null;
            }
            
            // 获取伴侣用户信息
            User partnerUser = baseMapper.findUserById(currentUser.getPartnerId());
            if (partnerUser == null) {
                log.warn("伴侣用户不存在: partnerId={}", currentUser.getPartnerId());
                return null;
            }
            
            log.info("成功获取伴侣信息: userId={}, partnerId={}", userId, partnerUser.getId());
            return partnerUser;
        } catch (Exception e) {
            log.error("获取用户伴侣信息异常: userId={}", userId, e);
            return null;
        }
    }
    
    /**
     * 绑定情侣关系
     * @param userId 用户ID
     * @param partnerId 伴侣ID
     * @return 是否绑定成功
     */
    @Override
    public boolean bindPartner(Long userId, Long partnerId) {
        log.info("开始绑定情侣关系: userId={}, partnerId={}", userId, partnerId);
        
        if (userId == null || partnerId == null) {
            log.warn("用户ID或伴侣ID为空: userId={}, partnerId={}", userId, partnerId);
            return false;
        }
        
        try {
            // 获取用户信息
            User user = baseMapper.findUserById(userId);
            User partner = baseMapper.findUserById(partnerId);
            
            if (user == null || partner == null) {
                log.warn("用户或伴侣不存在: userId={}, partnerId={}", userId, partnerId);
                return false;
            }
            
            // 更新双方的partnerId
            user.setPartnerId(partnerId);
            partner.setPartnerId(userId);
            
            // 更新时间
            user.setUpdateTime(LocalDateTime.now());
            partner.setUpdateTime(LocalDateTime.now());
            
            // 保存更新
            boolean result1 = this.updateById(user);
            boolean result2 = this.updateById(partner);
            
            boolean success = result1 && result2;
            if (success) {
                log.info("情侣关系绑定成功: userId={}, partnerId={}", userId, partnerId);
            } else {
                log.error("情侣关系绑定失败: userId={}, partnerId={}", userId, partnerId);
            }
            
            return success;
        } catch (Exception e) {
            log.error("绑定情侣关系异常: userId={}, partnerId={}", userId, partnerId, e);
            return false;
        }
    }
    
    /**
     * 解除情侣关系
     * @param userId 用户ID
     * @return 是否解绑成功
     */
    @Override
    public boolean unbindPartner(Long userId) {
        log.info("开始解除情侣关系: userId={}", userId);
        
        if (userId == null) {
            log.warn("用户ID为空");
            return false;
        }
        
        try {
            // 获取当前用户信息
            User user = baseMapper.findUserById(userId);
            if (user == null) {
                log.warn("用户不存在: userId={}", userId);
                return false;
            }
            
            // 检查是否绑定了伴侣
            if (user.getPartnerId() == null) {
                log.warn("用户未绑定伴侣: userId={}", userId);
                return false;
            }
            
            // 获取伴侣信息
            User partner = baseMapper.findUserById(user.getPartnerId());
            if (partner == null) {
                log.warn("伴侣用户不存在: partnerId={}", user.getPartnerId());
                // 即使伴侣不存在，也要解除当前用户的绑定关系
                user.setPartnerId(null);
                user.setUpdateTime(LocalDateTime.now());
                return this.updateById(user);
            }
            
            // 解除双方的绑定关系
            user.setPartnerId(null);
            partner.setPartnerId(null);
            
            // 更新时间
            user.setUpdateTime(LocalDateTime.now());
            partner.setUpdateTime(LocalDateTime.now());
            
            // 保存更新
            boolean result1 = this.updateById(user);
            boolean result2 = this.updateById(partner);
            
            boolean success = result1 && result2;
            if (success) {
                log.info("情侣关系解除成功: userId={}, partnerId={}", userId, partner.getId());
            } else {
                log.error("情侣关系解除失败: userId={}, partnerId={}", userId, partner.getId());
            }
            
            return success;
        } catch (Exception e) {
            log.error("解除情侣关系异常: userId={}", userId, e);
            return false;
        }
    }
}